package com.lnyt.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lnyt.dao.t12306.TicketStore;
import com.lnyt.pojo.ticket.TicketTask;
import com.lnyt.pojo.ticket.TicketUser;
import com.lnyt.pojo.ticket.TrainNumber;
import com.lnyt.service.TicketAutoService;
import com.lnyt.service.TicketUserService;
import com.lnyt.service.TicketReqService;
import com.lnyt.util.CheckUtil;
import com.lnyt.util.TicketUtil;
import com.lnyt.util.factroy.OkHttpClientFactroy;
import com.lnyt.util.factroy.TicketFactroy;
import okhttp3.OkHttpClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


@Controller
@CrossOrigin(origins = "*", maxAge = 1800)
@RequestMapping(value = "/ticket")
public class TicketInterface {
    @Resource
    private TicketUserService ticketUserService;
    @Resource
    private TicketReqService ticketReqService;
    @Resource
    private TicketAutoService ticketAutoService;

    private Map<String, String> vueSessionMap;


    // 控制器初始化
    @PostConstruct
    public void initMethod() {
        vueSessionMap = new HashMap<>();

        // 添加服务观察者
        ticketAutoService.selfObservable().addObserver(ticketReqService);

        // 清理进程
        Runnable clean = new Runnable() {
            @Override
            public void run() {
                Calendar calendar = Calendar.getInstance(Locale.CHINA);
                Integer hour = calendar.get(Calendar.HOUR_OF_DAY);

                if (hour == 0) {
                    vueSessionMap.clear();
                }
            }
        };

        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleWithFixedDelay(clean, 1, 1, TimeUnit.HOURS);
    }

    // 会话确认
    @PostMapping(value = "/session")
    public void ticketSession(HttpServletRequest request,
                              HttpServletResponse response) {

        JSONObject result = new JSONObject();
        String sessionId = request.getSession().getId();

        if (vueSessionMap.containsKey(sessionId)) {
            String userId = vueSessionMap.get(sessionId);
            TicketUser ticketUser = ticketUserService.getTikcetUser(userId);
            JSONObject userJson = new JSONObject();
            userJson.put("userName",       ticketUser.getUserName());
            userJson.put("cellPhone",      ticketUser.getCellPhone());
            userJson.put("email",          ticketUser.getEmail());
            userJson.put("ticketUserName", ticketUser.getTicketUserName());

            result.put("status", 0);
            result.put("message", "用户已登录");
            result.put("user", userJson);
        } else {
            result.put("status", 1);
            result.put("message", "用户未登录");
        }

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSON.toJSONString(result));
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 使用者登陆
    @PostMapping(value = "/login")
    public void tiketUserLogin(HttpServletRequest request,
                               HttpServletResponse response,
                               @RequestBody String reqBody) {

        // OkHttpClient okHttpClient = getUserServiceHttpClient(request);

        JSONObject reqData = JSON.parseObject(reqBody);
        String result = ticketUserService.userSignUp(reqData);
        JSONObject resData = JSON.parseObject(result);

        if (resData.getInteger("status") == 0) {
            String sessionId = request.getSession().getId();
            String userMd5 = CheckUtil.calcMd5(resData.getString("userName"));

            vueSessionMap.put(sessionId, userMd5);
        }

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(result);
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 初始化
    @PostMapping(value = "/init")
    public void tiketInit(HttpServletRequest request,
                          HttpServletResponse response) {

        OkHttpClient okHttpClient = getUserServiceHttpClient(request);

        ticketReqService.signInit(okHttpClient);

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(ticketReqService.signUamtk(okHttpClient));
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 得到验证码
    @PostMapping(value = "/captach")
    public void tiketCaptach(HttpServletRequest request,
                             HttpServletResponse response) {

        OkHttpClient okHttpClient = getUserServiceHttpClient(request);

        String base64Img = ticketReqService.signCaptch(okHttpClient);

        try {
            if (base64Img != null) {
                response.getWriter().write(base64Img);
            }
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 验证登陆
    @PostMapping(value = "/uamtk")
    public void tiket12306Uamtk(HttpServletRequest request,
                                HttpServletResponse response) {

        OkHttpClient okHttpClient = getUserServiceHttpClient(request);
        // JSONObject resData = JSON.parseObject(ticketReqService.signUamtk(okHttpClient));

        JSONObject reqData = new JSONObject();
        reqData.put("_json_att", "");
        JSONObject resData = JSON.parseObject(ticketReqService.orderCheckUser(reqData, okHttpClient));

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSON.toJSONString(resData));
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 12306用户登录
    @PostMapping(value = "/connect")
    public void tiket12306Login(HttpServletRequest request,
                                HttpServletResponse response,
                                @RequestBody String reqBody) {

        OkHttpClient okHttpClient = getUserServiceHttpClient(request);

        JSONObject reqData = JSON.parseObject(reqBody);
        JSONObject resData = null;

        String userMd5 = vueSessionMap.get(request.getSession().getId());

        if (userMd5 == null) {
            resData = new JSONObject();
            resData.put("result_code", 4);
        } else {
            TicketUser ticketUser = ticketUserService.getTikcetUser(userMd5);
            reqData.put("_json_att", "");
            reqData.put("username", ticketUser.getTicketUserName());
            reqData.put("password", ticketUser.getTicketPassWord());

            // 验证码
            resData = JSON.parseObject(ticketReqService.signCaptchCheck(reqData, okHttpClient));
            if (resData.getInteger("result_code") == 4) {
                // 登录
                resData = JSON.parseObject(ticketReqService.signLogin(reqData, okHttpClient));
                if (resData.getInteger("result_code") == 0) {
                    // 校验
                    resData = JSON.parseObject(ticketReqService.signUamtk(okHttpClient));
                    if (resData.getInteger("result_code") == 0) {
                        reqData.put("tk", resData.getString("newapptk"));
                        // 握手
                        resData = JSON.parseObject(ticketReqService.signUamauthClient(reqData, okHttpClient));

                        ticketUserService.getTikcetUser(userMd5).setTicketStatus(TicketStore.LOGINED);
                        ticketUserService.getTikcetUser(userMd5).setOkHttpClient(okHttpClient);
                        vueSessionMap.put(request.getSession().getId(), userMd5);
                    }
                }
            }
        }

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSON.toJSONString(resData));
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 管理任务
    @PostMapping(value = "/manage")
    public void manageOrderList(HttpServletRequest request,
                                HttpServletResponse response,
                                @RequestBody String reqBody) {

        String taskId = request.getSession().getId();
        String userMd5 = vueSessionMap.get(taskId);
        String resBody = null;

        if (userMd5 != null) {
            TicketTask ticketTask = new TicketTask();
            ticketTask.setUserId(userMd5);
            resBody = ticketUserService.selectTask(ticketTask, null);
        } else {
            resBody = "{\"status\":\"notLogin\"}";
        }

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(resBody);
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 车站信息
    @PostMapping(value = "/station")
    public void ticketOrderStation(HttpServletResponse response) {
        String result = ticketUserService.getStationInfoAll();

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(result);
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 查询车次
    @PostMapping(value = "/query")
    public void tiketOrderQuery(HttpServletRequest request,
                                HttpServletResponse response,
                                @RequestBody String reqBody) {

        OkHttpClient okHttpClient = getUserServiceHttpClient(request);

        List<TrainNumber> trainNumberList = new ArrayList<>();
        JSONObject reqData = JSON.parseObject(reqBody);
        JSONObject resData = JSON.parseObject(ticketReqService.queryTicket(reqData, okHttpClient));

        if (resData != null && resData.getInteger("httpstatus") == 200) {
            JSONArray trainNumberData = resData.getJSONObject("data").getJSONArray("result");

            for (String item : trainNumberData.toJavaList(String.class)) {
                trainNumberList.add(TicketFactroy.createTrainNumber(item));
            }
        }

        //trainNumberList.sort();

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSONArray.toJSONString(trainNumberList));
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 查询乘客
    @PostMapping(value = "/passenger")
    public void tiketPassenger(HttpServletRequest request,
                               HttpServletResponse response) {

        OkHttpClient okHttpClient = getUserServiceHttpClient(request);

        JSONObject reqData = new JSONObject();
        reqData.put("_json_att", "");
        reqData.put("REPEAT_SUBMIT_TOKEN", "");

        JSONObject resData = JSON.parseObject(ticketReqService.queryPassenger(reqData, okHttpClient));
        JSONObject resVue = null;

        if (resData != null && resData.getInteger("httpstatus") == 200) {
            resVue = resData.getJSONObject("data");
        }

        try {
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSONObject.toJSONString(resVue));
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 新建任务
    @PostMapping(value = "/new")
    public void ticketNewList(HttpServletRequest request,
                              HttpServletResponse response,
                              @RequestBody String reqBody) {

        OkHttpClient okHttpClient = getUserServiceHttpClient(request);

        TicketTask ticketTask = JSON.parseObject(reqBody, TicketTask.class);

        ticketTask.setUserId(vueSessionMap.get(request.getSession().getId()));
        ticketTask.setTrainId(TicketUtil.calcTrainMd5(ticketTask));
        ticketTask.setCreatDate(TicketUtil.getDate());
        ticketTask.setStatus("Work");

        try {
            ticketUserService.insertTask(ticketTask, okHttpClient);

            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSON.toJSONString(ticketTask));
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 取消任务
    @PostMapping(value = "/del")
    public void ticketDelList(HttpServletRequest request,
                              HttpServletResponse response,
                              @RequestBody String reqBody) {

        OkHttpClient okHttpClient = getUserServiceHttpClient(request);

        TicketTask ticketTask = JSON.parseObject(reqBody, TicketTask.class);
        ticketTask.setStatus("Cencel");

        try {
            ticketUserService.updataTask(ticketTask, okHttpClient);
            ticketUserService.getTikcetUser(ticketTask.getUserId()).getTicketTaskMap().remove(ticketTask.getId());

            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSON.toJSONString(ticketTask));
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    // 得到当前会话的 Http Obj
    private OkHttpClient getUserServiceHttpClient(HttpServletRequest request) {
        boolean isNew = false;
        OkHttpClient okHttpClient = null;

        HttpSession httpSession = request.getSession(false);

        if (httpSession == null) {
            httpSession = request.getSession(true);
            isNew = httpSession.isNew();
        }

        String taskId = httpSession.getId();
        String userMd5 = vueSessionMap.get(taskId);

        if (isNew || userMd5 == null) {
            okHttpClient = OkHttpClientFactroy.creator();
        } else {
            okHttpClient = ticketUserService.getTikcetUser(userMd5).getOkHttpClient();
        }

        return okHttpClient;
    }
}
